Python 小型项目大全 26~30

您所在的位置:网站首页 start a fire中文字幕 Python 小型项目大全 26~30

Python 小型项目大全 26~30

2023-04-13 16:01| 来源: 网络整理| 查看: 265

二十六、斐波那契

原文:http://inventwithpython.com/bigbookpython/project26.html 斐波那契数列是一个著名的数学模式,被认为是 13 世纪意大利数学家斐波那契的杰作(尽管其他人发现它的时间更早)。序列从 0 和 1 开始,下一个数字总是前两个数字的和。这个序列永远继续下去:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987 . . .

斐波那契数列在音乐创作、股票市场预测、向日葵头上的小花图案以及许多其他领域都有应用。这个程序可以让你计算出你想要的序列。更多关于斐波那契数列的信息可以在en.wikipedia.org/wiki/Fibonacci_number找到。

运行示例

当您运行fibonacci.py时,输出如下所示:

Fibonacci Sequence, by Al Sweigart email@protected `--snip--` Enter the Nth Fibonacci number you wish to calculate (such as 5, 50, 1000, 9999), or QUIT to quit: > 50 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 7778742049工作原理

因为斐波那契数字很快变得非常大,所以第 46 到 50 行检查用户是否输入了 10,000 或更大的数字,并显示一个警告,提示输出可能需要一些时间才能在屏幕上完成。虽然你的程序几乎可以瞬间完成数百万次计算,但将文本打印到屏幕上相对较慢,可能需要几秒钟。我们程序中的警告提醒用户,他们总是可以通过按下Ctrl+C来终止程序。

"""Fibonacci Sequence, by Al Sweigart email@protected Calculates numbers of the Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13... This code is available at https://nostarch.com/big-book-small-python-programming Tags: short, math""" import sys print('''Fibonacci Sequence, by Al Sweigart email@protected The Fibonacci sequence begins with 0 and 1, and the next number is the sum of the previous two numbers. The sequence continues forever: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987... ''') while True: # Main program loop. while True: # Keep asking until the user enters valid input. print('Enter the Nth Fibonacci number you wish to') print('calculate (such as 5, 50, 1000, 9999), or QUIT to quit:') response = input('> ').upper() if response == 'QUIT': print('Thanks for playing!') sys.exit() if response.isdecimal() and int(response) != 0: nth = int(response) break # Exit the loop when the user enteres a valid number. print('Please enter a number greater than 0, or QUIT.') print() # Handle the special cases if the user entered 1 or 2: if nth == 1: print('0') print() print('The #1 Fibonacci number is 0.') continue elif nth == 2: print('0, 1') print() print('The #2 Fibonacci number is 1.') continue # Display warning if the user entered a large number: if nth >= 10000: print('WARNING: This will take a while to display on the') print('screen. If you want to quit this program before it is') print('done, press Ctrl-C.') input('Press Enter to begin...') # Calculate the Nth Fibonacci number: secondToLastNumber = 0 lastNumber = 1 fibNumbersCalculated = 2 print('0, 1, ', end='') # Display the first two Fibonacci numbers. # Display all the later numbers of the Fibonacci sequence: while True: nextNumber = secondToLastNumber + lastNumber fibNumbersCalculated += 1 # Display the next number in the sequence: print(nextNumber, end='') # Check if we've found the Nth number the user wants: if fibNumbersCalculated == nth: print() print() print('The #', fibNumbersCalculated, ' Fibonacci ', 'number is ', nextNumber, sep='') break # Print a comma in between the sequence numbers: print(', ', end='') # Shift the last two numbers: secondToLastNumber = lastNumber lastNumber = nextNumber

在输入源代码并运行几次之后,尝试对其进行实验性的修改。你也可以自己想办法做到以下几点:

使用不同于 0 和 1 的起始数字。通过将前三个数字而不是前两个数字相加来创建下一个数字。探索程序

这是一个基础程序,所以没有太多的选项来定制它。相反,考虑一下:你如何使用这个程序?还有哪些有用的序列可以被编程?

二十七、鱼缸

原文:http://inventwithpython.com/bigbookpython/project27.html

在一个虚拟鱼缸里观看你自己的虚拟鱼,里面有气泡器和海藻植物。每次你运行这个程序,它会用不同的鱼类型和颜色随机生成鱼。休息一下,享受这个软件水族馆的平静安详,或者尝试在一些虚拟鲨鱼中编程来恐吓它的居民!您不能从 IDE 或编辑器中运行该程序。该程序使用bext模块,必须从命令提示符或终端运行才能正确显示。关于bext模块的更多信息可以在pypi.org/project/bext找到。运行示例

图 27-1 显示了运行fishtank.py时的输出。

:鱼缸程序的输出,有几条鱼、海藻和泡泡

工作原理

现代图形程序通常通过擦除整个窗口并每秒重绘 30 或 60 次来生成动画。这给了他们每秒 30 或 60 帧(FPS)的帧速率。FPS 越高,动画运动就越流畅。

绘制到终端窗口要慢得多。如果我们擦除整个终端窗口,用bext模块重新绘制它的内容,我们通常只能得到大约 3 或 4 FPS。这将导致窗口明显闪烁。

我们可以通过只在终端窗口发生变化的部分绘制字符来加快速度。鱼缸程序的大部分输出是空白空间,所以为了让元素移动,clearAquarium()只需要在鱼、海藻和泡泡当前所在的地方画出' '个空格字符。这增加了我们的帧速率,减少了闪烁,并使鱼缸动画更加令人愉快。

"""Fish Tank, by Al Sweigart email@protected A peaceful animation of a fish tank. Press Ctrl-C to stop. Similar to ASCIIQuarium or @EmojiAquarium, but mine is based on an older ASCII fish tank program for DOS. https://robobunny.com/projects/asciiquarium/html/ https://twitter.com/EmojiAquarium This code is available at https://nostarch.com/big-book-small-python-programming Tags: extra-large, artistic, bext""" import random, sys, time try: import bext except ImportError: print('This program requires the bext module, which you') print('can install by following the instructions at') print('https://pypi.org/project/Bext/') sys.exit() # Set up the constants: WIDTH, HEIGHT = bext.size() # We can't print to the last column on Windows without it adding a # newline automatically, so reduce the width by one: WIDTH -= 1 NUM_KELP = 2 # (!) Try changing this to 10. NUM_FISH = 10 # (!) Try changing this to 2 or 100. NUM_BUBBLERS = 1 # (!) Try changing this to 0 or 10. FRAMES_PER_SECOND = 4 # (!) Try changing this number to 1 or 60. # (!) Try changing the constants to create a fish tank with only kelp, # or only bubblers. # NOTE: Every string in a fish dictionary should be the same length. FISH_TYPES = [ {'right': ['>'], 'left': ['||>'], 'left': [''], 'left': ['||.'], 'left': ['o||)).'], 'left': ['o[['], 'left': [''], 'left': ['', '-._.-._^=>', '._.-._.^=>'], 'left': [' 0 and board[(x - 1, y)] == charToChange: # Recursive Case: Change the left neighbor's tile: changeTile(tileType, board, x - 1, y, charToChange) if y > 0 and board[(x, y - 1)] == charToChange: # Recursive Case: Change the top neighbor's tile: changeTile(tileType, board, x, y - 1, charToChange) if x < BOARD_WIDTH - 1 and board[(x + 1, y)] == charToChange: # Recursive Case: Change the right neighbor's tile: changeTile(tileType, board, x + 1, y, charToChange) if y < BOARD_HEIGHT - 1 and board[(x, y + 1)] == charToChange: # Recursive Case: Change the bottom neighbor's tile: changeTile(tileType, board, x, y + 1, charToChange) def hasWon(board): """Return True if the entire board is one color/shape.""" tile = board[(0, 0)] for x in range(BOARD_WIDTH): for y in range(BOARD_HEIGHT): if board[(x, y)] != tile: return False return True # If this program was run (instead of imported), run the game: if __name__ == '__main__': main()

在输入源代码并运行几次之后,尝试对其进行实验性的修改。标有(!)的注释对你可以做的小改变有建议。你也可以自己想办法做到以下几点:

添加其他形状和颜色。创建除矩形之外的其他纸板形状。探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

如果将第 92 行的board = {}改为board = [],会得到什么错误信息?如果将第 105 行的return board改为return None,会得到什么错误信息?如果把第 76 行的movesLeft -= 1改成movesLeft -= 0会怎么样?二十九、森林火灾模拟

原文:http://inventwithpython.com/bigbookpython/project29.html 这个模拟展示了一个森林,它的树木不断生长,然后被烧毁。在模拟的每一步中,有 1%的可能性一片空白长成一棵树,有 1%的可能性一棵树被闪电击中并烧毁。大火会蔓延到邻近的树木,所以密集的森林比稀疏的森林更容易遭受更大的火灾。这个模拟的灵感来自尼基·凯斯在ncase.me/simulating/model的表情符号。

运行示例

当您运行forestfiresim.py时,输出将如下所示:

:森林火灾模拟,绿色A表示树木,红色W表示火焰

工作原理

这个模拟是涌现行为的一个例子——系统中简单部分之间的相互作用创造了复杂的模式。空地长成树,闪电把树变成火,火又把树变回空地,同时蔓延到邻近的树。通过调整树木生长和雷击率,您可以使森林显示不同的现象。例如,闪电几率低但生长率高会导致持续的大面积森林火灾,因为树木往往彼此靠近并迅速补充。增长率低,但雷击几率高,会引发几起小火灾,但由于附近缺乏树木,这些小火灾很快就会熄灭。我们不会显式地对这些行为进行编程;相反,它自然地从我们创造的系统中出现。

"""Forest Fire Sim, by Al Sweigart email@protected A simulation of wildfires spreading in a forest. Press Ctrl-C to stop. Inspired by Nicky Case's Emoji Sim http://ncase.me/simulating/model/ This code is available at https://nostarch.com/big-book-small-python-programming Tags: short, bext, simulation""" import random, sys, time try: import bext except ImportError: print('This program requires the bext module, which you') print('can install by following the instructions at') print('https://pypi.org/project/Bext/') sys.exit() # Set up the constants: WIDTH = 79 HEIGHT = 22 TREE = 'A' FIRE = 'W' EMPTY = ' ' # (!) Try changing these settings to anything between 0.0 and 1.0: INITIAL_TREE_DENSITY = 0.20 # Amount of forest that starts with trees. GROW_CHANCE = 0.01 # Chance a blank space turns into a tree. FIRE_CHANCE = 0.01 # Chance a tree is hit by lightning & burns. # (!) Try setting the pause length to 1.0 or 0.0: PAUSE_LENGTH = 0.5 def main(): forest = createNewForest() bext.clear() while True: # Main program loop. displayForest(forest) # Run a single simulation step: nextForest = {'width': forest['width'], 'height': forest['height']} for x in range(forest['width']): for y in range(forest['height']): if (x, y) in nextForest: # If we've already set nextForest[(x, y)] on a # previous iteration, just do nothing here: continue if ((forest[(x, y)] == EMPTY) and (random.random() 4 1234567 +-------+ |.......| |.......| |XXX.XO.| |OOOOXO.| |OOOXOX.| |OXXXOXX| +-------+ Player O has won!工作原理

本书中的棋盘游戏项目遵循类似的程序结构。通常有一个字典或列表来表示棋盘的状态,一个getNewBoard()函数返回棋盘的数据结构,一个displayBoard()函数在屏幕上呈现棋盘的数据结构,等等。你可以查看本书中带有桌游标签的其他项目,并相互比较,尤其是当你想创建自己的原创桌游程序时。

"""Four in a Row, by Al Sweigart email@protected A tile-dropping game to get four in a row, similar to Connect Four. This code is available at https://nostarch.com/big-book-small-python-programming Tags: large, game, board game, two-player""" import sys # Constants used for displaying the board: EMPTY_SPACE = '.' # A period is easier to count than a space. PLAYER_X = 'X' PLAYER_O = 'O' # Note: Update displayBoard() & COLUMN_LABELS if BOARD_WIDTH is changed. BOARD_WIDTH = 7 BOARD_HEIGHT = 6 COLUMN_LABELS = ('1', '2', '3', '4', '5', '6', '7') assert len(COLUMN_LABELS) == BOARD_WIDTH def main(): print("""Four in a Row, by Al Sweigart email@protected Two players take turns dropping tiles into one of seven columns, trying to make four in a row horizontally, vertically, or diagonally. """) # Set up a new game: gameBoard = getNewBoard() playerTurn = PLAYER_X while True: # Run a player's turn. # Display the board and get player's move: displayBoard(gameBoard) playerMove = askForPlayerMove(playerTurn, gameBoard) gameBoard[playerMove] = playerTurn # Check for a win or tie: if isWinner(playerTurn, gameBoard): displayBoard(gameBoard) # Display the board one last time. print('Player ' + playerTurn + ' has won!') sys.exit() elif isFull(gameBoard): displayBoard(gameBoard) # Display the board one last time. print('There is a tie!') sys.exit() # Switch turns to other player: if playerTurn == PLAYER_X: playerTurn = PLAYER_O elif playerTurn == PLAYER_O: playerTurn = PLAYER_X def getNewBoard(): """Returns a dictionary that represents a Four in a Row board. The keys are (columnIndex, rowIndex) tuples of two integers, and the values are one of the 'X', 'O' or '.' (empty space) strings.""" board = {} for columnIndex in range(BOARD_WIDTH): for rowIndex in range(BOARD_HEIGHT): board[(columnIndex, rowIndex)] = EMPTY_SPACE return board def displayBoard(board): """Display the board and its tiles on the screen.""" '''Prepare a list to pass to the format() string method for the board template. The list holds all of the board's tiles (and empty spaces) going left to right, top to bottom:''' tileChars = [] for rowIndex in range(BOARD_HEIGHT): for columnIndex in range(BOARD_WIDTH): tileChars.append(board[(columnIndex, rowIndex)]) # Display the board: print(""" 1234567 +-------+ |{}{}{}{}{}{}{}| |{}{}{}{}{}{}{}| |{}{}{}{}{}{}{}| |{}{}{}{}{}{}{}| |{}{}{}{}{}{}{}| |{}{}{}{}{}{}{}| +-------+""".format(*tileChars)) def askForPlayerMove(playerTile, board): """Let a player select a column on the board to drop a tile into. Returns a tuple of the (column, row) that the tile falls into.""" while True: # Keep asking player until they enter a valid move. print('Player {}, enter a column or QUIT:'.format(playerTile)) response = input('> ').upper().strip() if response == 'QUIT': print('Thanks for playing!') sys.exit() if response not in COLUMN_LABELS: print('Enter a number from 1 to {}.'.format(BOARD_WIDTH)) continue # Ask player again for their move. columnIndex = int(response) - 1 # -1 for 0-based the index. # If the column is full, ask for a move again: if board[(columnIndex, 0)] != EMPTY_SPACE: print('That column is full, select another one.') continue # Ask player again for their move. # Starting from the bottom, find the first empty space. for rowIndex in range(BOARD_HEIGHT - 1, -1, -1): if board[(columnIndex, rowIndex)] == EMPTY_SPACE: return (columnIndex, rowIndex) def isFull(board): """Returns True if the `board` has no empty spaces, otherwise returns False.""" for rowIndex in range(BOARD_HEIGHT): for columnIndex in range(BOARD_WIDTH): if board[(columnIndex, rowIndex)] == EMPTY_SPACE: return False # Found an empty space, so return False. return True # All spaces are full. def isWinner(playerTile, board): """Returns True if `playerTile` has four tiles in a row on `board`, otherwise returns False.""" # Go through the entire board, checking for four-in-a-row: for columnIndex in range(BOARD_WIDTH - 3): for rowIndex in range(BOARD_HEIGHT): # Check for horizontal four-in-a-row going right: tile1 = board[(columnIndex, rowIndex)] tile2 = board[(columnIndex + 1, rowIndex)] tile3 = board[(columnIndex + 2, rowIndex)] tile4 = board[(columnIndex + 3, rowIndex)] if tile1 == tile2 == tile3 == tile4 == playerTile: return True for columnIndex in range(BOARD_WIDTH): for rowIndex in range(BOARD_HEIGHT - 3): # Check for vertical four-in-a-row going down: tile1 = board[(columnIndex, rowIndex)] tile2 = board[(columnIndex, rowIndex + 1)] tile3 = board[(columnIndex, rowIndex + 2)] tile4 = board[(columnIndex, rowIndex + 3)] if tile1 == tile2 == tile3 == tile4 == playerTile: return True for columnIndex in range(BOARD_WIDTH - 3): for rowIndex in range(BOARD_HEIGHT - 3): # Check for four-in-a-row going right-down diagonal: tile1 = board[(columnIndex, rowIndex)] tile2 = board[(columnIndex + 1, rowIndex + 1)] tile3 = board[(columnIndex + 2, rowIndex + 2)] tile4 = board[(columnIndex + 3, rowIndex + 3)] if tile1 == tile2 == tile3 == tile4 == playerTile: return True # Check for four-in-a-row going left-down diagonal: tile1 = board[(columnIndex + 3, rowIndex)] tile2 = board[(columnIndex + 2, rowIndex + 1)] tile3 = board[(columnIndex + 1, rowIndex + 2)] tile4 = board[(columnIndex, rowIndex + 3)] if tile1 == tile2 == tile3 == tile4 == playerTile: return True return False # If the program is run (instead of imported), run the game: if __name__ == '__main__': main()

在输入源代码并运行几次之后,尝试对其进行实验性的修改。标有(!)的注释对你可以做的小改变有建议。你也可以自己想办法做到以下几点:

创建三排或五排变体。做一个这个游戏的三人变种。添加一个“通配符”牌,该牌在玩家回合后随机掉落,并且可以由任何一个玩家使用。添加任一玩家都不能使用的“阻止”牌。探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

如果把第 11 行的PLAYER_O = 'O'改成PLAYER_O = 'X'会怎么样?如果把 116 行的return (columnIndex, rowIndex)改成return (columnIndex, 0)会怎么样?如果把第 98 行的response == 'QUIT'改成response != 'QUIT'会怎么样?如果将第 72 行的tileChars = []改为tileChars = {},会得到什么错误信息?


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3